//-----------------------------------------------
//    module name: 
//    author: Liang
//  
//    version: 1st version (2021-10-01)
//    description: 
//        
//
//
//-----------------------------------------------
`timescale 1ns / 1ps
`include "/team/riscv/rtl/riscv.h"
module soc_top(
`ifdef POST_SYNTHSIS_SIMULATION
    input  wire        clk_in_p    ,
    input  wire        clk_in_n    ,
`else
    input  wire        clk_pad  ,
`endif 
    input  wire        rstn_pad        , 
    input  wire        rx_pin_pad      ,    
    output wire        tx_pin_pad      ,
    
    input  wire        spi_miso_pad,    // SPI MISO????
    output wire        spi_mosi_pad,    // SPI MOSI????
    output wire        spi_ss_pad,      // SPI SS????
    output wire        spi_clk_pad,     // SPI CLK????
    
    inout  wire [`GPIO_NUM-1:0]  io_pin_pad             //GPIO 
    );

    //?????????????? rx ?? tx ???? , ????????????
    wire        init_rx ;       wire        uart_rx ;   
    wire        init_tx ;       wire        uart_tx ;   

    wire [`GPIO_NUM-1:0] io_pin;
    wire [31:0] gpio_ctrl_o;
    wire [31:0] gpio_data_o;
    
    wire        clk;
    wire        rstn_async;
    wire        rstn_finish;
    //wire        init_enable_async;
    wire        rstn;
    wire        init_sig;
    wire        rx_pin;
    wire        tx_pin;
    wire        spi_miso;    
    wire        spi_mosi;    
    wire        spi_ss;      
    wire        spi_clk;   
    wire [ 4:0] int_timer;

    wire        Local_in_R;
    wire        Local_out_R;
    wire [50:0] Local_in; 
    wire [50:0] Local_out;
    wire        Local_out_A; 
    wire        Local_in_A;
    
    wire        West_in_R;                  wire        East_in_R;
    wire        West_out_R;                 wire        East_out_R;
    wire [50:0] West_in;                    wire [50:0] East_in;
    wire [50:0] West_out;                   wire [50:0] East_out;
    wire        West_out_A;                 wire        East_out_A;
    wire        West_in_A;                  wire        East_in_A;
    
    wire        North_in_R;                 wire        South_in_R;
    wire        North_out_R;                wire        South_out_R;
    wire [50:0] North_in;                   wire [50:0] South_in;
    wire [50:0] North_out;                  wire [50:0] South_out;
    wire        North_out_A;                wire        South_out_A;
    wire        North_in_A;                 wire        South_in_A;
    
    localparam input_DO   = 1'b0; localparam output_DI   = 1'bz;   
    localparam input_OE   = 1'b0; localparam output_OE   = 1'b1; 
    localparam input_IDDQ = 1'b0; localparam output_IDDQ = 1'b0; localparam inout_IDDQ = 1'b0;
    localparam input_PD   = 1'b1; localparam output_PD   = 1'b0; localparam inout_PD   = 1'b1;
    localparam input_PU   = 1'b1; localparam output_PU   = 1'b0; localparam inout_PU   = 1'b1;
    localparam input_SMT  = 1'b1; localparam output_SMT  = 1'b0; localparam inout_SMT  = 1'b1;
    localparam input_SR   = 1'b0; localparam output_SR   = 1'b0; localparam inout_SR   = 1'b0;
    localparam input_PIN2 = 1'b0; localparam output_PIN2 = 1'b1; localparam inout_PIN2 = 1'b1;
    localparam input_PIN1 = 1'b0; localparam output_PIN1 = 1'b1; localparam inout_PIN1 = 1'b1;

`ifdef DC_ENV 

//-----INPUT IO PAD
    IUMA input_clk(
                .PAD   (clk_pad),.DI (clk),
                .OE    (input_OE  ),.IDDQ  (input_IDDQ),.PD    (input_PD  ),
                .PU    (input_PU  ),.SMT   (input_SMT ),.DO    (input_DO  ),
                .SR    (input_SR  ),.PIN2  (input_PIN2),.PIN1  (input_PIN1)//,.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
        );
    IUMA input_rstn(
                .PAD   (rstn_pad),.DI    (rstn_async),
                .OE    (input_OE  ),.IDDQ  (input_IDDQ),.PD    (input_PD  ),
                .PU    (input_PU  ),.SMT   (input_SMT ),.DO    (input_DO  ),
                .SR    (input_SR  ),.PIN2  (input_PIN2),.PIN1  (input_PIN1)//,.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
        );
    /*IUMA input_init_enable(
                .PAD   (init_enable_pad),.DI (init_enable),
                .OE    (input_OE  ),.IDDQ  (input_IDDQ),.PD    (input_PD  ),
                .PU    (input_PU  ),.SMT   (input_SMT ),.DO    (input_DO  ),
                .SR    (input_SR  ),.PIN2  (input_PIN2),.PIN1  (input_PIN1),.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
        );*/
    IUMA input_rx_pin(
                .PAD   (rx_pin_pad),.DI    (rx_pin),
                .OE    (input_OE  ),.IDDQ  (input_IDDQ),.PD    (input_PD  ),
                .PU    (input_PU  ),.SMT   (input_SMT ),.DO    (input_DO  ),
                .SR    (input_SR  ),.PIN2  (input_PIN2),.PIN1  (input_PIN1)//,.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
        );    
    IUMA input_spi_miso(
                .PAD   (spi_miso_pad),.DI  (spi_miso),
                .OE    (input_OE  ),.IDDQ  (input_IDDQ),.PD    (input_PD  ),
                .PU    (input_PU  ),.SMT   (input_SMT ),.DO    (input_DO  ),
                .SR    (input_SR  ),.PIN2  (input_PIN2),.PIN1  (input_PIN1)//,.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
        );        
//-----OUTPUT IO PAD
    IUMA output_tx_pin(
                .PAD   (tx_pin_pad), .DO   (tx_pin),
                .OE    (output_OE  ),.IDDQ (output_IDDQ),.PD    (output_PD  ),
                .PU    (output_PU  ),.SMT  (output_SMT ),//.DI    (output_DI  ),
                .SR    (output_SR  ),.PIN2 (output_PIN2),.PIN1  (output_PIN1)//,.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
        );                                                      
    IUMA output_spi_mosi(                                       
                .PAD   (spi_mosi_pad), .DO   (spi_mosi),        
                .OE    (output_OE  ),.IDDQ (output_IDDQ),.PD    (output_PD  ),
                .PU    (output_PU  ),.SMT  (output_SMT ),//.DI    (output_DI  ),
                .SR    (output_SR  ),.PIN2 (output_PIN2),.PIN1  (output_PIN1)//,.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
        );                                                      
    IUMA output_spi_ss(                                         
                .PAD   (spi_ss_pad), .DO   (spi_ss),            
                .OE    (output_OE  ),.IDDQ (output_IDDQ),.PD    (output_PD  ),
                .PU    (output_PU  ),.SMT  (output_SMT ),//.DI    (output_DI  ),
                .SR    (output_SR  ),.PIN2 (output_PIN2),.PIN1  (output_PIN1)//,.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
        );                                                      
    IUMA output_spi_clk(                                        
                .PAD   (spi_clk_pad), .DO   (spi_clk),          
                .OE    (output_OE  ),.IDDQ (output_IDDQ),.PD    (output_PD  ),
                .PU    (output_PU  ),.SMT  (output_SMT ),//.DI    (output_DI  ),
                .SR    (output_SR  ),.PIN2 (output_PIN2),.PIN1  (output_PIN1)//,.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
        );

    genvar i; 
    generate
       for(i=0;i<`GPIO_NUM;i=i+1)
       begin: gpio
            IUMA inout_gpio_i(
                .PAD   (io_pin_pad[i]),  .OE    (gpio_ctrl_o[i]),
                .DO    (gpio_data_o[i]), .DI    (io_pin[i]), 
                .PD    (inout_PD  ),.PU    (inout_PU  ),.SMT   (inout_SMT ), .IDDQ  (inout_IDDQ),
                .SR    (inout_SR  ),.PIN2  (inout_PIN2),.PIN1  (inout_PIN1)//,.VSS(1'b0),.VDD(1'b1),.VSSIO(1'b0),.VDDIO(1'b1)
            );
       end
    endgenerate

`else 
    //input
    `ifdef POST_SYNTHSIS_SIMULATION
        clk_wiz_0 clkgen(
        
            .clk_in1_n  (clk_in_n   ),
            .clk_in1_p  (clk_in_p   ),
            .resetn     (rstn       ),
            .clk_out1   (clk        )
            
        );   
    `else
    assign clk          = clk_pad;
    `endif
    assign rstn_async   = rstn_pad;
    assign rx_pin       = rx_pin_pad;
    assign spi_miso     = spi_miso_pad   ;
    //output
    assign tx_pin_pad   = tx_pin;
    assign spi_mosi_pad = spi_mosi  ;
    assign spi_ss_pad   = spi_ss    ;
    assign spi_clk_pad  = spi_clk   ;

   genvar i; 
    generate
       for(i=0;i<`GPIO_NUM;i=i+1)
       begin: io_ctrlpin
            //assign io_pin_pad[i] = gpio_ctrl_o[i] ? gpio_data_o[i] : 1'bz;
    IOBUF #(
            .DRIVE(12), // Specify the output drive strength
            .IBUF_LOW_PWR("TRUE"),  // Low Power - "TRUE", High Performance = "FALSE"
            .IOSTANDARD("DEFAULT"), // Specify the I/O standard
            .SLEW("SLOW") // Specify the output slew rate
        ) IOBUF_inst_io0 (
            .O(io_pin[i]),     // IO_pad输入。管脚经过IBUF缓冲输出到内部信号
            .IO(io_pin_pad[i]),   // pad接口/管脚
            .I(gpio_data_o[i]),        // 输出到IO_pad。内部信号经过OBUF缓冲到管脚
            .T(gpio_ctrl_o[i])   // 当IO_pad需要输入的时候，使能OBUF使其输出高组态。
        );
       end
    endgenerate

    assign io_pin  = io_pin_pad;
`endif

    async2sync async2sync_rstnInit  (.clk(clk),.rst_async_n(rstn_async),.rst_sync_n(rstn));
    async2sync async2sync_rstnFinish(.clk(clk),.rst_async_n(~init_sig& rstn),.rst_sync_n(rstn_finish));

    assign tx_pin  = init_sig ? init_tx : uart_tx;
    assign init_rx = init_sig ? rx_pin  : 1'b1   ;
    assign uart_rx = init_sig ? 1'b1    : rx_pin ;

`ifdef BUS_BY_FUTONG
     nodeTop bus(
        .localInR(Local_in_R),.localOutR(Local_out_R),.i_localInMsg_51(Local_in),.o_localMsg_51(Local_out),.localInA(Local_in_A),.localOutA(Local_out_A),
        .westInR(West_in_R),.westOutR(West_out_R),.i_westInMsg_51(West_in),.o_westMsg_51(West_out),.westInA(West_in_A),.westOutA(West_out_A),
        .eastInR(East_in_R),.eastOutR(East_out_R),.i_eastInMsg_51(East_in),.o_eastMsg_51(East_out),.eastInA(East_in_A),.eastOutA(East_out_A),
        .northInR(North_in_R),.northOutR(North_out_R),.i_northInMsg_51(North_in),.o_northMsg_51(North_out),.northInA(North_in_A),.northOutA(North_out_A),
        .southInR(South_in_R),.southOutR(South_out_R),.i_southInMsg_51(South_in),.o_southMsg_51(South_out),.southInA(South_in_A),.southOutA(South_out_A),
        .rst(rstn_finish)
    );

`endif

`ifdef BUS_BY_WEIJIE
    center_node_top_code bus(
        .Local_in_R(Local_in_R),.Local_out_R(Local_out_R),    .Local_in(Local_in),    .Local_out(Local_out),    .Local_click_in_A(Local_in_A),    .Local_click_out_A(Local_out_A),
        .West_in_R(West_in_R),  .West_out_R(West_out_R),.West_in(West_in),.West_out(West_out),.West_click_in_A(West_in_A),.West_click_out_A(West_out_A),
        .East_in_R(East_in_R),  .East_out_R(East_out_R),.East_in(East_in),.East_out(East_out),.East_click_in_A(East_in_A),.East_click_out_A(East_out_A),
        .South_in_R(South_in_R),.South_out_R(South_out_R),.South_in(South_in),.South_out(South_out),.South_click_out_A(South_out_A),.South_click_in_A(South_in_A),
        .North_in_R(North_in_R),.North_out_R(North_out_R),.North_in(North_in),.North_out(North_out),.North_click_out_A(North_out_A),.North_click_in_A(North_in_A),
        .rstn(rstn_finish)
    );
`endif

    cpu_slot cpu_slot   (
    
        .clk           (clk               ),
        .rstn          (rstn              ),
        .rstn_finish   (rstn_finish       ),
        
        .init_sig      (init_sig          ),
        .init_rx       (init_rx           ),
        .init_tx       (init_tx           ),
        .int_sig_cpu   (int_timer         ),
        
        .outR          (Local_in_R        ),
        .inR           (Local_out_R       ),
        .data_to       (Local_in          ),
        .data_from     (Local_out         ),
        .inA           (Local_out_A       ),
        .outA          (Local_in_A        )
    );                                    
                                          
    uart_slot uart_slot (   
    
        .clk           (clk               ),
        .rstn          (rstn_finish       ),   
        .tx_pin        (uart_tx           ),
        .rx_pin        (uart_rx           ),

        .outR          (West_in_R         ),
        .inR           (West_out_R        ),
        .data_to       (West_in           ),
        .data_from     (West_out          ),
        .inA           (West_out_A        ),
        .outA          (West_in_A         )
    );                                      
                                          
    gpio_slot gpio_slot (     
    
        .clk           (clk               ),
        .rstn          (rstn_finish       ),   
        .io_pin_i      (io_pin            ),
        .gpio_ctrl_o   (gpio_ctrl_o      ),
        .gpio_data_o   (gpio_data_o      ),

        .outR          (South_in_R        ),
        .inR           (South_out_R       ),
        .data_to       (South_in          ),
        .data_from     (South_out         ),
        .inA           (South_out_A       ),
        .outA          (South_in_A        )
    );                                      

   timer_slot timer_slot(    
   
        .clk           (clk               ),
        .rstn          (rstn_finish       ),   
        .int_sig_o     (int_timer         ),
                                         
        .outR          (North_in_R        ),
        .inR           (North_out_R       ),
        .data_to       (North_in          ),
        .data_from     (North_out         ),
        .inA           (North_out_A       ),
        .outA          (North_in_A        )
    );

   spi_slot spi_slot(
   
        .clk           (clk               ),
        .rstn          (rstn_finish       ),    
        .spi_mosi      (spi_mosi          ),
        .spi_miso      (spi_miso          ),
        .spi_ss        (spi_ss            ),
        .spi_clk       (spi_clk           ),
                                         
        .outR          (East_in_R        ),
        .inR           (East_out_R       ),
        .data_to       (East_in          ),
        .data_from     (East_out         ),
        .inA           (East_out_A       ),
        .outA          (East_in_A        )
    );

endmodule
